
package org.opendatakit.collect.android.views;

import java.io.File;

import org.apache.commons.lang.StringEscapeUtils;
import org.opendatakit.collect.android.activities.FormEntryActivity;
import org.opendatakit.collect.android.application.Collect;

import android.content.Context;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.webkit.ConsoleMessage;
import android.webkit.JsResult;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebSettings.RenderPriority;
import android.webkit.WebStorage.QuotaUpdater;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.TableLayout;

/**
 * This class is
 * 
 * @author carlhartung
 */
public class JQueryODKView extends FrameLayout {

    // starter random number for view IDs
	private static final String t = "JQueryODKView";

	
	private WebView mWebView;

	private String getHtmlUrl() {
		File mediaFolder = Collect.getInstance().getFormController().getMediaFolder();
		String instanceID = Collect.getInstance().getFormController().getSubmissionMetadata().instanceId;
        // File htmlFile = new File(mediaFolder, mPrompt.getAppearanceHint());
        File htmlFile = new File(mediaFolder, "index.html");
        String htmlUrl = "file://" + htmlFile.getAbsolutePath() +
        		"?instanceId=" + StringEscapeUtils.escapeHtml(instanceID);
        return htmlUrl;
	}
	
    public JQueryODKView(FormEntryActivity activity, JQueryJavascriptCallback jsCallback, boolean asHierarchy) {
    	super(activity);
        
		mWebView = new WebView(activity);
		mWebView.setId(984732);
		
        FrameLayout.LayoutParams fp = new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        TableLayout.LayoutParams params = new TableLayout.LayoutParams();
        params.setMargins(7, 5, 7, 5);
        mWebView.setLayoutParams(params);

        mWebView.addJavascriptInterface(jsCallback, "opendatakit");
        mWebView.setWebChromeClient(new WebChromeClient() {

			@Override
			public void getVisitedHistory(ValueCallback<String[]> callback) {
				callback.onReceiveValue(new String[] {});
			}

			@Override
			public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
				Log.i(t, consoleMessage.sourceId() +
						"[" + consoleMessage.lineNumber() + "]: " + 
						consoleMessage.message());
				return true;
			}

			@Override
			public void onExceededDatabaseQuota(String url,
					String databaseIdentifier, long currentQuota,
					long estimatedSize, long totalUsedQuota,
					QuotaUpdater quotaUpdater) {
				long space = (4 + (currentQuota / 65536L )) * 65536L;
				Log.i(t, "Extending Database quota to: " + Long.toString(space));
				quotaUpdater.updateQuota(space);
			}

			@Override
			public void onReachedMaxAppCacheSize(long spaceNeeded,
					long totalUsedQuota, QuotaUpdater quotaUpdater) {
				long space = (4 + (spaceNeeded / 65536L )) * 65536L;
				Log.i(t, "Extending AppCache quota to: " + Long.toString(space));
				quotaUpdater.updateQuota(space);
			}

			@Override
			public void onConsoleMessage(String message, int lineNumber,
					String sourceID) {
				Log.w(t, sourceID + "[" + lineNumber + "]: " + message );
			}

			@Override
			public boolean onJsAlert(WebView view, String url, String message,
					JsResult result) {
				Log.w(t, url + ": " + message );
				return false;
			}
        	
        });
        WebViewClient wvc = new WebViewClient() {

			@Override
			public void doUpdateVisitedHistory(WebView view, String url,
					boolean isReload) {
				Log.i(t, "doUpdateVisitedHistory: " + url);
			}

			@Override
			public void onLoadResource(WebView view, String url) {
				Log.i(t, "onLoadResource: " + url);
				super.onLoadResource(view, url);
			}

			@Override
			public void onPageFinished(WebView view, String url) {
				Log.i(t, "onPageFinished: " + url);
				super.onPageFinished(view, url);
			}

			@Override
			public void onReceivedError(WebView view, int errorCode,
					String description, String failingUrl) {
				Log.i(t, "onReceivedError: " + failingUrl);
				super.onReceivedError(view, errorCode, description, failingUrl);
			}

			@Override
			public void onScaleChanged(WebView view, float oldScale,
					float newScale) {
				Log.i(t, "onScaleChanged: " + newScale);
				super.onScaleChanged(view, oldScale, newScale);
			}

			@Override
			public void onTooManyRedirects(WebView view, Message cancelMsg,
					Message continueMsg) {
				Log.i(t, "onTooManyRedirects: " + cancelMsg.toString());
				super.onTooManyRedirects(view, cancelMsg, continueMsg);
			}

			@Override
			public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
				Log.i(t, "onUnhandledKeyEvent: " + event.toString());
				super.onUnhandledKeyEvent(view, event);
			}};
		
		mWebView.setWebViewClient(wvc);
        
        // for development -- always draw from source...
        WebSettings ws = mWebView.getSettings();
        ws.setAllowFileAccess(true);
        ws.setAppCacheEnabled(true);
        ws.setAppCacheMaxSize(1024L*1024L*200L);
        ws.setAppCachePath(Collect.METADATA_PATH + File.separator + "appCache");
        ws.setCacheMode(WebSettings.LOAD_NO_CACHE);
        ws.setDatabaseEnabled(true);
        ws.setDatabasePath(Collect.METADATA_PATH + File.separator + "webDb");
        ws.setDefaultFixedFontSize(Collect.getQuestionFontsize());
        ws.setDefaultFontSize(Collect.getQuestionFontsize());
        ws.setDomStorageEnabled(true);
        ws.setGeolocationDatabasePath(Collect.METADATA_PATH + File.separator + "geoCache");
        ws.setGeolocationEnabled(true);
        ws.setJavaScriptCanOpenWindowsAutomatically(true);
        ws.setJavaScriptEnabled(true);
        ws.setRenderPriority(RenderPriority.HIGH);
        
        // disable to try to solve touch/mouse/swipe issues
        ws.setBuiltInZoomControls(false);
        ws.setSupportZoom(false);
        
        mWebView.setFocusable(true);
        mWebView.setFocusableInTouchMode(true);
        mWebView.setInitialScale(100);
        
        // questionable value...
        mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        mWebView.setSaveEnabled(true);
        
        addView(mWebView, fp);
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(mWebView, InputMethodManager.SHOW_IMPLICIT);

        loadPage(asHierarchy ? "#hierarchy" : "#opening");
    }

    public void triggerSaveAnswers(boolean asComplete) {
    	// NOTE: this is asynchronous
    	loadJavascriptUrl("javascript:(function() {save_all_changes(" + (asComplete ? "true" : "false") + ");})()");
    }

    ///////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////
    

    // called to invoke a javascript method inside the webView
    public void loadJavascriptUrl(String javascriptUrl) {
    	mWebView.loadUrl(javascriptUrl);
    }
    
	public void loadPage(String pageRef) {
		mWebView.loadUrl(getHtmlUrl() + pageRef);
		mWebView.requestFocus();
	}


}
